package com.tuling.jucdemo.hashmap;

import java.util.HashMap;
import java.util.Iterator;

/**
 * @author :tangweiliang
 * @date : 2022/12/2 16:57
 * 未来的你会感谢现在努力的自己
 *
 * 使用hashmap的remove方法报错
 *
 * 报错的代码是：
 * final Entry<K,V> nextEntry() {
 *             if (modCount != expectedModCount)
 *                 throw new ConcurrentModificationException();
 *             Entry<K,V> e = next;
 *             if (e == null)
 *                 throw new NoSuchElementException();
 *
 *             if ((next = e.next) == null) {
 *                 Entry[] t = table;
 *                 while (index < t.length && (next = t[index++]) == null)
 *                     ;
 *             }
 *             current = e;
 *             return e;
 *         }
 *
 * 原因：hashmap的remove()方法中也会modCount++操作,modCount != expectedModCount
 * jdk1.7中的removeEntryForKey()方法 modCount++
 * 如何解决：使用Iterator(迭代器)的remove方法 它会在每次remove重新赋值
 *         public void remove() {
 *             if (current == null)
 *                 throw new IllegalStateException();
 *             if (modCount != expectedModCount)
 *                 throw new ConcurrentModificationException();
 *             Object k = current.key;
 *             current = null;
 *             HashMap.this.removeEntryForKey(k);
 *             expectedModCount = modCount; //重新赋值
 *         }
 *
 */
public class ExceptionTest {
    public static void main(String[] args) {
        HashMap<String,String> hashMap = new HashMap<>(); //对象.modCount
        hashMap.put("1", "2"); // 1
        hashMap.put("2", "2"); // 2
        Iterator i$ = hashMap.keySet().iterator(); // KeyIterator迭代器 modCount=expectedModCount=2

        // 快速失败 fast-fail
        while(i$.hasNext()) {
            String key = (String)i$.next(); // 第一次循环modCount与expectedModCount是否相等(第一次相等)
            if (key.equals("2")) {
                //hashMap.remove(key); // modCount++ 修改
                i$.hasNext();
            }
        }
    }
}

